package cn.conac.rc.gateway.security.service;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import cn.conac.rc.framework.utils.StringUtils;
import cn.conac.rc.gateway.security.vo.JwtUser;

/**
 * spring security 密码验证
 * @author zhangfz
 * @version 1.0
 */
public class AuthenticationProviderImpl implements AuthenticationProvider {
  
    /**
     * userDetailsService
     */
    private final UserDetailsService userDetailsService;

    public AuthenticationProviderImpl(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;

        String username = token.getName();
        if (org.apache.commons.lang3.StringUtils.isBlank(username)) {
            throw new UsernameNotFoundException("用户名/密码无效");
        }
        // 从数据库找到的用户
        JwtUser jwtUser = null;
        jwtUser = (JwtUser)userDetailsService.loadUserByUsername(username);
        //
        if (jwtUser == null) {
            throw new UsernameNotFoundException("用户名/密码无效");
        } else if (!jwtUser.isEnabled()) {
            throw new DisabledException("用户已被禁用");
        } else if (!jwtUser.isAccountNonExpired()) {
            throw new AccountExpiredException("账号已过期");
        } else if (!jwtUser.isAccountNonLocked()) {
            throw new LockedException("账号已被锁定");
        } else if (!jwtUser.isCredentialsNonExpired()) {
            throw new LockedException("凭证已过期");
        }
        String plainPassword = (String) token.getCredentials();
//        userDetails.getPassword()
        // 对收到的密码进行AES对称解密
        //plainPassword = AesUtils.decode(plainPassword, AES_SECRET);
        // 数据库用户的密码
        String password = jwtUser.getPassword();
        // 与authentication里面的credentials相比较
        if (!"1".equals(jwtUser.getIsMobileLogin()) && !validatePassword(plainPassword, password)) {
            throw new BadCredentialsException("错误的用户名或密码");
        }

        // 授权
        return new UsernamePasswordAuthenticationToken(jwtUser, password, jwtUser.getAuthorities());
    }

    /**
     * 验证密码
     * @param plainPassword 明文密码
     * @param password 密文密码
     * @return 验证成功返回true
     */
    public static boolean validatePassword(String plainPassword, String password) {
        return DigestUtils.md5Hex(plainPassword).equals(password);
    }

    /**
     * 对明文密码进行处理
     * @param plainPassword 明文密码
     * @return String 经过处理后的密码
     * @author wangmeng
     */
    public static String entryptPassword(String plainPassword) {
        return DigestUtils.md5Hex(plainPassword);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        // 返回true后才会执行上面的authenticate方法,这步能确保authentication能正确转换类型
        return UsernamePasswordAuthenticationToken.class.equals(authentication);
    }

}